package com.ruoyi.framework.aspectj.commonservice.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author: silver
 * created:11/21/22
 * description
 */
public class InvocationDigestInterceptor implements MethodInterceptor {
    private static final String MISSED = "-";
    private final Logger logger;
    private String appName;
    private boolean resolveResult;

    public InvocationDigestInterceptor(final String logger) {
        this.logger = LoggerFactory.getLogger(logger);
    }

    public Object invoke(final MethodInvocation invocation) throws Throwable {
        if (!this.logger.isInfoEnabled()) {
            return invocation.proceed();
        } else {
            long begin = System.currentTimeMillis();
            Object result = null;
            Throwable exception = null;
            boolean var12 = false;

            Object var6;
            try {
                var12 = true;
                result = invocation.proceed();
                var6 = result;
                var12 = false;
            } catch (Throwable var13) {
                exception = var13;
                throw var13;
            } finally {
                if (var12) {
                    String digestInfo = this.createDigestInfo(invocation, begin, result, exception);
                    this.logger.info("({})", digestInfo);
                }
            }

            String digestInfo = this.createDigestInfo(invocation, begin, result, exception);
            this.logger.info("({})", digestInfo);
            return var6;
        }
    }

    private String createDigestInfo(final MethodInvocation invocation, final long begin, final Object result, final Throwable exception) {
        long end = System.currentTimeMillis();
        String elapsed = end - begin + "ms";
        Method method = invocation.getMethod();
        String methodName = method.getName();
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(invocation.getThis());
        boolean isJdkProxy = Proxy.isProxyClass(targetClass);
        String targetClassName = isJdkProxy ? method.getDeclaringClass().getSimpleName() : targetClass.getSimpleName();
        String success = exception == null ? "T" : "F";
        String code;
        code = "-";

        return String.join(",", this.appName, targetClassName, methodName, success, code, elapsed);
    }

    public void setAppName(final String appName) {
        this.appName = appName;
    }

    public void setResolveResult(final boolean resolveResult) {
        this.resolveResult = resolveResult;
    }
}
